package com.myFwk.service.serviceImpl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.enums.ApiErrorCode;
import com.baomidou.mybatisplus.extension.exceptions.ApiException;
import com.myFwk.constant.Constants;
import com.myFwk.domain.SysMenu;
import com.myFwk.feign.OAuth2FeignClient;
import com.myFwk.model.JwtToken;
import com.myFwk.model.LoginResult;
import com.myFwk.service.LoginService;
import com.myFwk.service.SysMenuService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.jwt.Jwt;
import org.springframework.security.jwt.JwtHelper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author GL
 * @version 1.0
 * @date 2021/9/1 21:26
 */
@Service
@Slf4j
public class LoginServiceImpl implements LoginService {

    @Autowired
    private OAuth2FeignClient auth2FeignClient;
    @Autowired
    private SysMenuServiceImpl sysMenuService;
    @Autowired
    private RedisTemplate redisTemplate;




    @Override
    public LoginResult login(String username, String password) {
        log.info("用户{}开始登录", username);
        //获取用户token 通过远程调用
        ResponseEntity<JwtToken> tokenResponse = auth2FeignClient.getToken("password", username, password, "admin_type");
        if (tokenResponse.getStatusCode() != HttpStatus.OK) {
            throw new ApiException(ApiErrorCode.FAILED);
        }
        JwtToken jwtToken = tokenResponse.getBody();
        String accessToken = jwtToken.getAccessToken();
        log.info("远程调用授权服务器成功,获取Token：{}", accessToken);
        //解析Token
        Jwt jwt = JwtHelper.decode(accessToken);
        String jwtJson = jwt.getClaims();
        JSONObject jsonObject = JSON.parseObject(jwtJson);
        //获取用户Id
        Long userId = Long.valueOf(jsonObject.getString("user_name"));
        //根据用户Id获取菜单列表
        List<SysMenu> menuList = sysMenuService.getMenusByUserId(userId);
        //解析Token信息获取权限信息
        JSONArray authorities = jsonObject.getJSONArray("authorities");
        List<SimpleGrantedAuthority> grantList = authorities.stream().map(authoritie -> new SimpleGrantedAuthority(authoritie.toString())).collect(Collectors.toList());
        //将Token放入Redis当中，
        redisTemplate.opsForValue().set(accessToken, "", Long.valueOf(jwtToken.getExpiresIn()), TimeUnit.SECONDS);
        //给返回前端的Token添加token 类型
        return new LoginResult(jwtToken.getTokenType() + " " + accessToken, menuList, grantList);
    }
}
